package oaSystem.web.security.aop;

import java.lang.reflect.Method;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import oaSystem.entity.Employee;
import oaSystem.entity.Function;
import oaSystem.entity.Role;
import oaSystem.web.security.Authorize;
import oaSystem.web.security.exception.AuthorityException;

@Component
@Aspect
public class SecurityAdvice {
	@Autowired
	private HttpSession session;
	
	@Pointcut("@annotation(oaSystem.web.security.Authorize)") 
	public void bizPointcut(){} 
	
	@Before("bizPointcut()")
	public void doBefor(JoinPoint jp){ 
		//判断员工是否登录
		Employee employee=(Employee)session.getAttribute("user");
		if(employee==null){
			throw new AuthorityException("login",new Throwable("您还没有登录"));
		}
		Method method= ((MethodSignature)jp.getSignature()).getMethod();
		
		Authorize annotation = method.getAnnotation(Authorize.class);
		if(annotation==null){//方法没有注解
			annotation=jp.getTarget().getClass().getAnnotation(Authorize.class);

			if(annotation==null){//类没有注解（一般是登录页面）
				return;
			}
		}
		String rules = annotation.rules();
		if(rules==null||rules.isEmpty()){
			return;
		}
		if(containsRoles(rules,employee.getRoles())){
			return;
		}
		throw new AuthorityException("error",new Throwable("您没有访问权限"));
	}
	/**
	 * 抽取方法（查询是否有权限）
	 * @param rules
	 * @param roles
	 * @return
	 */
	private boolean containsRoles(String rules, List<Role> roles) {
		if(roles!=null&&roles.size()>0){
			for (Role role : roles) {
				List<Function> functions = role.getFunctionAll();
				for (Function function : functions) {
					if(rules.equals(function.getCode())){
						return true;
					}
				}
			}
		}
		return false;
	}
}
